﻿
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Jade.Tools.SL.Windows.Extensions;
using JulMar.Silverlight.Interfaces;
using JulMar.Silverlight.Mvvm;
using JulMar.Siverlight.Helpers.Interactivity;
using MediaBrowserSL.RIA.MediaBrowserServiceReference;
using MediaBrowserSL.RIA.MvvmUtils;
using MediaBrowserSL.RIA.MvvmUtils.UI;
using MediaBrowserSL.RIA.Services;
using SLMitsuControls;
using System.ServiceModel;

namespace MediaBrowserSL.RIA.ViewModels
{
    /// <summary>
    /// Page Book View Model
    /// </summary>
    public class PageBooksViewModel : PageViewModelBase, IDataProvider
    {
        #region Private member

        private IErrorVisualizer errorVisualizer;
        private List<Border> pages;
        private UCBook book;
        private bool isGenerating;
        private bool isDeleting;
        private ICustomMessageBoxVisualizer customMessageBoxVisualizer;
        private IManageBooksVisualizer manageBooksVisualizer;

        #endregion

        #region Public Properties

        public override string Name
        {
            get { return "Page Books"; }
        }

        public bool IsGenerating
        {
            get { return isGenerating; }
            set
            {
                isGenerating = value;
                if (value)
                {
                    SendMessage(MediatorMessages.UpdateViewLogOut, false);
                }
                else
                {
                    SendMessage(MediatorMessages.UpdateViewLogOut, true);
                }
                OnPropertyChanged("IsGenerating");
            }
        }

        public int CurrentSheetIndex
        {
            get
            {
                if (book != null)
                {
                    return book.CurrentSheetIndex;
                }
                else
                {
                    return 1;
                }
            }
            set
            {
                if (book != null)
                {
                    if (value <= Math.Floor((double)(pages.Count / 2)))
                    {
                        book.CurrentSheetIndex = value;
                        OnPropertyChanged("CurrentSheetIndex");
                    }
                }
            }
        }

        public String CountPage
        {
            get
            {
                return " / " + Math.Floor((double)(pages.Count / 2));
            }
        }

        public bool IsDeleting
        {
            get
            {
                return isDeleting;
            }
            set
            {

                isDeleting = value;
                OnPropertyChanged("IsDeleting");
            }
        }

        #endregion

        #region Comand

        public ICommand BookOpenCommand
        {
            get;
            private set;
        }

        public ICommand BackwardPageCommand
        {
            get;
            private set;
        }

        public ICommand ForwardPageCommand
        {
            get;
            private set;
        }

        public DelegatingCommand PrepareAddBookCommand
        {
            get;
            private set;
        }

        public DelegatingCommand PrepareUpdateBookCommand
        {
            get;
            private set;
        }

        public DelegatingCommand DeleteBookCommand
        {
            get;
            private set;
        }

        #endregion

        public PageBooksViewModel(IMediaRiaServices service)
            : base(service)
        {
            pages = new List<Border>();

            BookOpenCommand = new DelegatingCommand<EventInformation>(BookOpen);
            BackwardPageCommand = new DelegatingCommand(BackwardPage);
            ForwardPageCommand = new DelegatingCommand(ForwardPage);

            PrepareAddBookCommand = new DelegatingCommand(PrepareAddBook);
            PrepareUpdateBookCommand = new DelegatingCommand(PrepareUpdateBook);
            DeleteBookCommand = new DelegatingCommand(DeleteBook);

            errorVisualizer = Resolve<IErrorVisualizer>();
            customMessageBoxVisualizer = Resolve<ICustomMessageBoxVisualizer>();
            manageBooksVisualizer = Resolve<IManageBooksVisualizer>();
        }

        #region private Methods

        /// <summary>
        /// Return Medias
        /// </summary>
        /// <param name="movies"></param>
        private void GetListMediasByCategory(IEnumerable<Media> books, Exception ex)
        {
            if (ex == null)
            {
                if (books != null)
                {
                    if (medias != null) { medias.Clear(); } else { medias = new ObservableCollection<Media>(); }
                    foreach (var m in books)
                    {
                        medias.Add(m);
                    }
                    sourceMediasView.Source = medias;
                    MediasView.MoveCurrentToFirst();
                    SelectedItem = CurrentMedia;
                    sourceMediasView.View.CurrentChanged += View_CurrentChanged;
                    OnPropertyChanged("MediasView");
                    View_CurrentChanged(null, null);
                }
            }
            else
            {
                if (customMessageBoxVisualizer != null)
                {
                    customMessageBoxVisualizer.Show(null, ((FaultException<ErrorDataContract>)ex).Detail.Detail, ex.Message, MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }

        void View_CurrentChanged(object sender, EventArgs e)
        {
            if (CurrentMedia != null)
            {
                lastMediaSelected = CurrentMedia;
                CreateBook();
                OnPropertyChanged("CurrentMedia");
            }
        }

        /// <summary>
        /// Book Open
        /// </summary>
        /// <param name="e"></param>
        private void BookOpen(EventInformation e)
        {
            bool createBook = false;
            if (book == null) { createBook = true; } else { book.OnPageTurned -= book_OnPageTurned; }

            book = e.CommandArgument as UCBook;
            book.OnPageTurned += book_OnPageTurned;

            if (createBook)
            {
                CreateBook();
            }
        }

        void book_OnPageTurned(int leftPageIndex, int rightPageIndex)
        {
            OnPropertyChanged("CurrentSheetIndex");
        }

        /// <summary>
        /// Create Book
        /// </summary>
        private void CreateBook()
        {
            if (book != null)
            {
                if (CurrentMedia != null)
                {
                    if (!isGenerating)
                    {
                        IsGenerating = true;
                        pages.Clear();
                        book.SetData(this);
                        service.GenerateImagesFromPdfBook(ImagesBookGenerated, CurrentMedia.UrlContent, SessionMb.CurrentUser);
                    }
                }
            }
        }

        /// <summary>
        /// Images Book Generated
        /// </summary>
        /// <param name="lImg"></param>
        /// <param name="ex"></param>
        private void ImagesBookGenerated(IEnumerable<String> lImg, Exception ex)
        {
            if (ex == null)
            {
                //BUG SelectedItem : If currentMedia is null => MoveCurrentToFirst
                if (CurrentMedia == null)
                {
                    sourceMediasView.View.CurrentChanged -= View_CurrentChanged;
                    MediasView.MoveCurrentTo(lastMediaSelected);
                    sourceMediasView.View.CurrentChanged += View_CurrentChanged;
                }
                //END BUG

                foreach (var p in lImg)
                {
                    Border border = new Border();
                    border.BorderThickness = new System.Windows.Thickness(1);
                    border.BorderBrush = new SolidColorBrush(Colors.Black);
                    Image img = new Image();
                    img.Stretch = System.Windows.Media.Stretch.Fill;
                    BitmapImage b = new BitmapImage();
                    b.UriSource = new Uri(p);
                    img.Source = b;
                    border.Child = img;
                    pages.Add(border);
                }
                book.SetData(this);
                OnPropertyChanged("CountPage");
            }
            else
            {
                if (customMessageBoxVisualizer != null)
                {
                    customMessageBoxVisualizer.Show(null, ((FaultException<ErrorDataContract>)ex).Detail.Detail, ex.Message, MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
            IsGenerating = false;
        }

        /// <summary>
        /// Previous Page
        /// </summary>
        private void BackwardPage()
        {
            if (!IsGenerating)
            {
                book.AnimateToPreviousPage(1000);
            }
        }

        /// <summary>
        /// Next Page
        /// </summary>
        private void ForwardPage()
        {
            if (!IsGenerating)
            {
                book.AnimateToNextPage(1000);
            }
        }

        #region Add/Update Book

        /// <summary>
        /// Prepare Add Book
        /// </summary>
        private void PrepareAddBook()
        {
            if (manageBooksVisualizer != null) manageBooksVisualizer.Show();
            SendMessage(MediatorMessages.EditBook, new Media());
        }

        /// <summary>
        /// Prepare Update Book
        /// </summary>
        private void PrepareUpdateBook()
        {
            if (CurrentMedia != null)
            {
                if (manageBooksVisualizer != null) manageBooksVisualizer.Show();
                SendMessage(MediatorMessages.EditBook, CurrentMedia);
            }
        }

        #endregion

        #region Delete Book

        /// <summary>
        /// Delete Movie
        /// </summary>
        private void DeleteBook()
        {
            if (CurrentMedia != null && !IsDeleting)
            {
                if (customMessageBoxVisualizer != null)
                {
                    customMessageBoxVisualizer.Show(ConfirmDeleteBook, "Etes-vous sur de vouloir supprimer ce Livre ?", "Supprimer", MessageBoxButton.OKCancel, MessageBoxImage.Question);
                }
                else
                {
                    IsDeleting = true;
                    service.DeleteMedia(MediaDeleted, CurrentMedia, SessionMb.CurrentUser);
                }
            }
        }

        /// <summary>
        /// Confimr Delete Book
        /// </summary>
        /// <param name="r"></param>
        private void ConfirmDeleteBook(MessageBoxResult r)
        {
            if (r == MessageBoxResult.OK)
            {
                IsDeleting = true;
                service.DeleteMedia(MediaDeleted, CurrentMedia, SessionMb.CurrentUser);
            }
        }

        /// <summary>
        /// Media Deleted
        /// </summary>
        /// <param name="e"></param>
        private void MediaDeleted(Exception ex)
        {
            IsDeleting = false;
            if (ex == null)
            {
                if (medias != null)
                {
                    medias.Remove(CurrentMedia); pages.Clear();
                    if (book != null) { book.SetData(this); }
                }
            }
            else
            {
                if (customMessageBoxVisualizer != null)
                {
                    customMessageBoxVisualizer.Show(null, ((FaultException<ErrorDataContract>)ex).Detail.Detail, ex.Message, MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }

        #endregion

        #endregion

        #region Public Methods

        /// <summary>
        /// Update Current User
        /// </summary>
        /// <param name="page"></param>
        [MessageMediatorTarget(MediatorMessages.UpdateCurrentUser)]
        public void UpdateCurrentUser(User user)
        {
            service.GetListMediasByCategory(GetListMediasByCategory, SessionMb.CurrentUser.Id, 4);
        }

        /// <summary>
        /// LogOut
        /// </summary>
        [MessageMediatorTarget(MediatorMessages.LogOut)]
        public void LogOut(User user)
        {
            if (medias != null)
            {
                medias.Clear();
                pages.Clear();
                if (book != null) { book.SetData(this); }
                MediaLookFor = String.Empty;
                OnPropertyChanged("CurrentMedia");
            }
            else
            {
                medias = new ObservableCollection<Media>();
            }
        }

        /// <summary>
        /// Add Book to List
        /// </summary>
        /// <param name="page"></param>
        [MessageMediatorTarget(MediatorMessages.AddBookToList)]
        public void AddBookToList(Media m)
        {
            if (medias != null) { medias.Add(m); }
            MediasView.MoveCurrentToLast();
        }

        /// <summary>
        /// Update Book to List
        /// </summary>
        /// <param name="page"></param>
        [MessageMediatorTarget(MediatorMessages.UpdateBookToList)]
        public void UpdateBookToList(Media m)
        {
            var movie = (from mo in Medias where m.Id == mo.Id select mo).SingleOrDefault();
            movie.Name = m.Name;
            movie.Description = m.Description;
        }

        #endregion

        #region IDataProvider Members

        public int GetCount()
        {
            return pages.Count;
        }

        public object GetItem(int index)
        {
            return pages[index];
        }

        #endregion
    }
}
